package tp.pr5.mv.window;

import java.awt.BorderLayout;
import java.util.Stack;

import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

import tp.pr5.mv.CPU;
import tp.pr5.mv.Controller;
import tp.pr5.mv.Observable;
import tp.pr5.mv.OperandStack;

@SuppressWarnings("serial")
public class VentanaPila extends JPanel implements OperandStack.Observer{

	/* Panel con un JTextArea que muestra el estado actual de la pila de la CPU que a su vez esta encapsulado
	 * en un JScrollPane. 
	 * También se dispone del panel AccionesPila, que permite interactuar con la pila de la CPU
	 * Se ha incluido un atributo de la clase Stack de Java para simular la pila de la CPU
	 * */
	
	private JTextArea textoPila;
	private Stack<Integer> pilaPanel;
	private JScrollPane pila;
	private AccionesPila accionesPila;
	
	public VentanaPila(Controller controller, Observable<CPU.Observer> observableCPU) {
		
		super( new BorderLayout() );
		setBorder(BorderFactory.createTitledBorder("Pila de operandos") );
		init(controller, observableCPU);
	}
	
	public void init(Controller controller, Observable<CPU.Observer> observableCPU) {
		
		textoPila = new JTextArea();
		textoPila.setEditable(false);
		textoPila.setColumns(25);
		
		pila = new JScrollPane(textoPila);
		add(pila, BorderLayout.CENTER);
		
		accionesPila = new AccionesPila(controller, observableCPU);
		add(accionesPila, BorderLayout.SOUTH);
		
		pilaPanel = new Stack<Integer>();
	}

	public void onPop(int val) {
		
		pilaPanel.pop();
		
		SwingUtilities.invokeLater(
				new Runnable() {
				 		public void run() {
				 			imprimePila();
				 		}
				}
		);
	}
	
	public void onPush(int val) {
		pilaPanel.push(val);
		SwingUtilities.invokeLater(
				new Runnable() {
				 		public void run() {
				 			imprimePila();
				 		}
				}
		);
	}
	
	public void onReset() {
		pilaPanel.removeAllElements();
		
		SwingUtilities.invokeLater(
				new Runnable() {
				 		public void run() {
				 			textoPila.setText("");
				 		}
				}
		);
	}
	

	public void imprimePila() {
		
		textoPila.setText("");     // Puesta en blanco del texto.
		
		for ( int i = pilaPanel.size() - 1; i != -1 ; i-- )     // Pintamos la pila.
		
			textoPila.append(pilaPanel.elementAt(i) + "\n");
		   
	}
	
	
}
